<template>
  <div id="app">
    <!-- 页面顶部导航 -->
    <header class="dashboard-header">
      <div class="header-left">
        <h1>信息追溯</h1>
      </div>
      <div class="header-center">
        <p>{{ currentTime }}</p>
      </div>
      <div class="header-right">
        <p>十四事业部装备中心开发</p>
      </div>
    </header>
    
      
      <!-- 分割线 -->
      <!-- 查询方式选择 -->
      
  <section class="query-section">
   <label :style="IsQualifiedStyle">{{ IsQualified?'✔ OK' : '✘ NG'  }}</label>
  <label for="query-type" class="query-label">查询方式:</label>
  <select v-model="queryType" id="query-type" class="query-select">
    <option value="assembly">按物料号查询</option>
    <option value="sn">按SN号查询</option>
    <option value="zc">按总成号查询</option>
  </select>
  <input
    v-model="queryInput"
    :placeholder="getPlaceholder()"
    class="query-input"
  />
  <button @click="fetchStationData" class="query-button">查询</button>
  <button @click="ExportExcel" class="query-button">数据导出</button>
  <div class="divcontainer_sub1">
            <span>
                <el-button round plain type="info" @click="openPort">连接串口</el-button>
                <el-button round plain type="info" @click="closePort">关闭串口</el-button>
            </span>
            <el-button class="circle-button" :style="serialColor"></el-button>  
        </div>
        
      </section>
      <div class="divid">
            <el-divider></el-divider>
        </div>
      <!-- 主模块布局 -->
      <div class="text-display">
        <div class="row">
      <div class="showCheckData-header">校验项</div>
      <div class="item" >
        <p>电机码</p>
      </div>
      <div class="item" >
        <p>电控码</p>
      </div>
      <div class="item" >
        <p>总成码</p>
      </div>
    </div>
    <div class="row">
      <div class="showCheckData-header">MES绑定数据</div>
      <div class="item" >
        <p>{{DJCode}}</p>
      </div>
      <div class="item" >
        <p>{{DKCode}}</p>
      </div>
      <div class="item" >
        <p>hhhhhh</p>
      </div>
    </div>
    <div class="row">
      <div class="showCheckData-header">扫码数据</div>
      <div class="item" >
        <p></p>
      </div>
      <div class="item" >
        <p></p>
      </div>
      <div class="item" >
        <p></p>
      </div>
    </div>
    <div class="row">
      <div class="showCheckData-header">校验结果</div>
      <div class="item" :style="{ backgroundColor: JudgeKeyMaterialResult[0] ? '#059669' : '#dc2626' }">
        {{ JudgeKeyMaterialResult[0] ? '✔ OK' : '✘ NG' }}
      </div>
      <div class="item" :style="{ backgroundColor: JudgeKeyMaterialResult[1] ? '#059669' : '#dc2626' }">
        {{ JudgeKeyMaterialResult[1] ? '✔ OK' : '✘ NG' }}
      </div>
      <div class="item" :style="{ backgroundColor: JudgeKeyMaterialResult[2] ? '#059669' : '#dc2626' }">
        {{ JudgeKeyMaterialResult[2] ? '✔ OK' : '✘ NG' }}
      </div>
    </div>
  </div>
  <div class="divid">
            <el-divider></el-divider>
        </div>
  <div class="main-grid">
  <!-- 工序进度模块 -->
  <section  class="module">
    <h2 class="module-title">工序进度</h2>
    <div class="process-grid" v-if="stateInfo.processList.length > 0">
      <div
        v-for="(process, index) in stateInfo.processList"
        :key="process.id"
        :class="['process-block', getProcessStatusClass(index)]"
        @click="showSignalOP(index)"
      >
       <p>{{ process.id }}</p> <p>{{ process.name }}</p>
      </div>
    </div>
    <div v-else>
      <p style="text-align: center; color: #aaa; font-size: 16px;">暂无工序进度数据</p>
    </div>
  </section>
   <!-- 弹窗组件 -->
   <el-dialog v-model="showModal" title="单工位信息" style="text-align: center;width:50%" >
                
     <!-- 物料绑定信息模块 -->
  <section class="module">
    <h2 class="module-title">物料绑定信息</h2>
    <div class="material-table-container">
      <table class="material-table">
      <thead>
        <tr>
          <th>上料工位号</th>
          <th>物料名称</th>
          <!-- <th>物料编码</th> -->
          <th>物料SN</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(material, index) in filtredMaterialItems" :key="index">
          <td>{{ material.stationId }}</td>
          <td>{{ material.materialName }}</td>
          <!-- <td>{{ material.materialCode }}</td> -->
          <td>{{ material.materialSN }}</td>
        </tr>
      </tbody>
    </table>
    </div>
   
    </section>
    <section class="module">
    <!-- 新增批次物料信息表 -->
    <h2 class="module-title" style="margin-top: 20px;">批次物料信息</h2>
    <div class="material-table-container">
      <table class="batch-material-table">
      <thead>
        <tr>
          <th>上料工位</th>
          <th>物料名称</th>
          <th>单次消耗量</th>
          <th>物料批次号</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(batch, index) in filtredBatchMaterialItems" :key="index">
          <td>{{ batch.station }}</td>
          <td>{{ batch.materialName }}</td>
          <td>{{ batch.consumption }}</td>
          <td>{{ batch.batchNumber }}</td>
        </tr>
      </tbody>
    </table>
    </div>
    
  </section>

  <!-- 生产参数模块 -->
  <section class="module">
    <h2 class="module-title">生产参数</h2>
    <div class="material-table-container">
    <table class="production-table">
      <thead>
        <tr>
          <th>工序号</th>
          <th>工序名称</th>
          <th>参数名称</th>
          <th>数值</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(param, index) in filtredProcessItems" :key="index">
          <td>{{ param.processId }}</td>
          <td>{{ param.processName }}</td>
          <td>{{ param.paramName }}</td>
          <td>{{ param.value }}</td>
        </tr>
      </tbody>
    </table>
    </div>
  </section>

   </el-dialog>

  <!-- 物料绑定信息模块 -->
  <section class="module">
    <h2 class="module-title">物料绑定信息</h2>
    <div class="material-table-container">
    <table class="material-table">
      <thead>
        <tr>
          <th>上料工位号</th>
          <th>物料名称</th>
          <th>物料编码</th>
          <th>物料SN</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(material, index) in stateInfo.materialInfo" :key="index">
          <td>{{ material.stationId }}</td>
          <td>{{ material.materialName }}</td>
          <td>{{ material.materialCode }}</td>
          <td>{{ material.materialSN }}</td>
        </tr>
      </tbody>
    </table>
    </div>
    <!-- 新增批次物料信息表 -->
    <h2 class="module-title" style="margin-top: 20px;">批次物料信息</h2>
    <div class="material-table-container">
    <table class="batch-material-table">
      <thead>
        <tr>
          <th>上料工位</th>
          <th>物料名称</th>
          <th>单次消耗量</th>
          <th>物料批次号</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(batch, index) in stateInfo.batchMaterialInfo" :key="index">
          <td>{{ batch.station }}</td>
          <td>{{ batch.materialName }}</td>
          <td>{{ batch.consumption }}</td>
          <td>{{ batch.batchNumber }}</td>
        </tr>
      </tbody>
    </table>
    </div>
  </section>

  <!-- 生产参数模块 -->
  <section class="module">
    <h2 class="module-title">生产参数</h2>
    <div class="material-table-container">
    <table class="production-table">
      <thead>
        <tr>
          <th>工序号</th>
          <th>工序名称</th>
          <th>参数名称</th>
          <th>数值</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(param, index) in stateInfo.productionParams" :key="index">
          <td>{{ param.processId }}</td>
          <td>{{ param.processName }}</td>
          <td>{{ param.paramName }}</td>
          <td>{{ param.value }}</td>
        </tr>
      </tbody>
    </table>
    </div>
  </section>
      </div>
   
   
    <!-- <el-tab-pane label="详细数据" name="tab2">
      
    </el-tab-pane> -->
   
    
  </div>
</template>

<script setup lang="ts" name="下线全检">
import { onMounted, ref,reactive, computed } from 'vue';
import request from '/@/utils/request';
import {  ElTabPane,ElTabs } from 'element-plus';
import other from '/@/utils/other';

const activeTab = ref('tab1');

// 响应式变量
const queryType = ref('assembly'); // 默认查询类型为SN号
const queryInput = ref('');
//const processList = ref([]);
const stateInfo = reactive({
  processList: [] as any[],
  materialInfo:[] as any[],// 物料绑定信息数据
  productionParams:[] as any[],// 生产参数数据
  batchMaterialInfo:[] as any[],//批次数据信息
  essentialBOMs:[] as any[],//批次数据信息
})



// 获取状态类
const getProcessStatusClass = (index: number) => {
  const status = stateInfo.processList[index]?.status;
  return status === 'OK' ? 'green' : 'red';
};


const showModal = ref(false);
const OperationCode = ref('');

const showSignalOP = (index:number) =>{
  showModal.value = !showModal.value,
  OperationCode.value=stateInfo.processList[index]?.id,
 console.log('OP',stateInfo.processList[index]?.id)
}



const filtredMaterialItems = computed(()=>{
  return stateInfo.materialInfo.filter(item=>String(item.stationId).includes(OperationCode.value))
})
const filtredBatchMaterialItems = computed(()=>{
  return stateInfo.batchMaterialInfo.filter(item=>String(item.station).includes(OperationCode.value))
})
const filtredProcessItems = computed(()=>{
  return stateInfo.productionParams.filter(item=>String(item.processId).includes(OperationCode.value))
})

/*********************串口使用*****************************/
//串口连接状态
const serialColor = ref('background-color:red;width:30px;height:30px;margin-top:8px') 
const port = ref(null);
const reader = ref(null);

//

//串口扫码数据
const textSN = ref('')
//扫码结果
const virtualSN = ref<string | null>(null)

//打开串口
const openPort = async () => {
    try {
        port.value = await navigator.serial.requestPort();
        await port.value.open({ baudRate: 115200 });
    } 
    catch (error) {
        alert("打开串口失败："+error)
    }

    if (port.value && port.value.readable){

        serialColor.value = "background-color:green;width:30px;height:30px";
    }
    else
    {
        serialColor.value = "background-color:red;width:30px;height:30px";
    }

    await readPort();
};

//关闭串口
const closePort = () => {

    if (reader.value) 
    {
        reader.value.cancel();
    }

    if (port.value) 
    {
        port.value.close();
    }
    
    if (port.value && port.value.readable)
    {
        serialColor.value = "background-color:green;width:30px;height:30px";
    }
    else
    {
        serialColor.value = "background-color:red;width:30px;height:30px";
    }
};

//读取串口
const readPort = async () => {
    textSN.value = "";
    if (port.value && port.value.readable) {

        reader.value = port.value.readable.getReader();
        try {
            var flag = true
            while (true) 
            {

                const { value, done } = await reader.value.read();
                if (done) 
                {
                    textSN.value = value;
                    break;
                }

                for (let i = 0; i < value.length; i++) 
                {
                    if(!flag)
                    {
                        flag = true
                        textSN.value = ''
                    }
                    textSN.value += String.fromCharCode(value[i]);
                    if (value[i] === 13) 
                    {
                        flag = false
                        // 扫码完成
                        console.log("ss",textSN.value)
                        textSN.value = textSN.value.replace('\r','').replace('\n', '').trim()

                        virtualSN.value = textSN.value,
                        queryInput.value = textSN.value,
                        request({
                              url: '/api/BaseInformation/Station/FinishPass',
                              method: 'post',
                              data: {
                                  'Type':queryType.value,
                                  'SN':virtualSN.value,
                                    }
                        }).then(res => {
                          stateInfo.materialInfo = res.materialRecords
                          stateInfo.processList=res.passRecords
                          stateInfo.productionParams = res.processDataRecords
                          stateInfo.batchMaterialInfo = res.batcInfoRecords
                        })
                    }
                }
            }

        } 
        catch (error) 
        {
            console.error(error);
        } 
        finally 
        {
            if (reader.value) {
                reader.value.releaseLock();
            }
        }
    }
};

/*********************************************************/
// 根据选择的查询类型返回输入框的占位符
const getPlaceholder = () => {
  switch (queryType.value) {
    case 'assembly':
      return '请输入物料号';
    case 'sn':
      return '请输入SN号';
    case 'zc':
      return '请输入总成号';
    default:
      return '请输入查询内容';
  }
};

const DJCode =ref('');
const DKCode = ref('');
// 查询数据
// 根据 `queryType` 处理查询逻辑
const fetchStationData = async() => {
  if (!queryInput.value) {
    alert(`请输入${getPlaceholder()}`);
    return;
  }
  await request({
        url: '/api/BaseInformation/Station/FinishPass',
        method: 'post',
        data: {
            'Type':queryType.value,
            'SN':queryInput.value
        }
    }).then(res => {
      stateInfo.materialInfo = res.materialRecords,
      stateInfo.processList=res.passRecords,
      stateInfo.productionParams = res.processDataRecords.sort((a:any, b:any) => a.processId - b.processId),
      stateInfo.batchMaterialInfo = res.batcInfoRecords,
      stateInfo.essentialBOMs = res.essentialBOMs
    })
    DJCode.value =stateInfo.materialInfo.length==0?'': stateInfo.materialInfo.find(x=>x.stationId=="2-OP3010-0").materialSN;
    DKCode.value = stateInfo.materialInfo.length==0?'':stateInfo.materialInfo.find(x=>x.stationId=="2-OP4040-0").materialSN;  
    console.log('ss',stateInfo.essentialBOMs);
    console.log(`查询方式: ${queryType.value}, 查询内容: ${queryInput.value}`);
  
};

/*************************************下线校验************/
const JudgeKeyMaterialResult = ref([true,true,false]);
const IsQualified = ref(false);
const IsQualifiedStyle = ref('background-color: gray;font-size: 25px;border-radius:50%;padding:10px;margin-right:40px;')


/**********************导出记录***************************/
const ExportExcel = () => {
  const data = stateInfo.materialInfo;

  const csvData = [];
  // 处理第一个数组
  if (stateInfo.materialInfo.length > 0) {
    // 添加标题行（假设第一个元素的键作为标题）
    const headers1 = Object.keys(stateInfo.materialInfo[0]);
    csvData.push(headers1);
    // 添加数据行
    const rows1 = stateInfo.materialInfo.map(row => Object.values(row));
    csvData.push(...rows1);
    // 添加分隔符（空行）
    csvData.push([]);
  }

  // 处理第二个数组
  if (stateInfo.productionParams.length > 0) {
    const headers2 = Object.keys(stateInfo.productionParams[0]);
    csvData.push(headers2);
    const rows2 = stateInfo.productionParams.map(row => Object.values(row));
    csvData.push(...rows2);
    csvData.push([]); // 分隔符
  }
  // 将每一行转换为数组，例如将对象的值提取出来
  const csvContent = csvData.map(row => {
    // 如果 row 是一个对象，提取它的值
    if (typeof row === 'object' && row !== null) {
      return Object.values(row).join(',');
    }
    // 如果 row 已经是数组，直接使用
    return row.join(',');
  }).join('\n');
  
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = queryInput.value+currentTime.value+'.csv'; 

  document.body.appendChild(a);
  a.click();

  document.body.removeChild(a);
  window.URL.revokeObjectURL(url);
}

// 当前时间
const currentTime = ref('');
const updateTime = () => {
  const now = new Date();
  currentTime.value = now.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  });
};
onMounted(() => {
  updateTime();
  setInterval(updateTime, 1000);
});
</script>


<style scoped lang="scss">
.dashboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(135deg, #1e3a8a 0%, #2563eb 50%, #1e3a8a 100%);
  padding: 15px 30px;
  color: white;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  position: relative;
  z-index: 100;
}

.dashboard-header::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, rgba(255,255,255,0.3), rgba(255,255,255,0.8), rgba(255,255,255,0.3));
}

.header-left h1 {
  margin: 0;
  font-size: 26px;
  font-weight: 600;
  text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
}

.header-center p,
.header-right p {
  margin: 0;
  font-size: 16px;
  opacity: 0.9;
}
.query-section {
  margin: 25px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 15px;
  background: #f8fafc;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.query-label {
  margin-right: 10px;
  font-size: 18px;
  font-weight: 600;
  color: #334155;
}

.query-select {
  height: 42px;
  padding: 0 15px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 16px;
  background: white;
  transition: all 0.3s;
}

.query-select:focus {
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
}

.query-input {
  padding: 10px 15px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 16px;
  width: 350px;
  transition: all 0.3s;
}

.query-input:focus {
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
}

.query-button {
  padding: 12px 24px;
  font-size: 16px;
  font-weight: 500;
  background: linear-gradient(to right, #1e3a8a, #2563eb);
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  height: 42px;
  transition: all 0.3s;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.query-button:hover {
  background: linear-gradient(to right, #2563eb, #1e40af);
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.query-button:active {
  transform: translateY(0);
}

/* 表格容器样式 */
.material-table-container,
.production-table-container,
.batch-material-table-container {
  max-height: 500px; /* 根据实际需要调整高度 */
  overflow-y: auto;
  margin-top: 15px;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  position: relative;
}

/* 表格基础样式 */
.material-table,
.production-table,
.batch-material-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
  table-layout: fixed;
}

/* 表头样式 */
.material-table thead,
.production-table thead,
.batch-material-table thead {
  position: sticky;
  top: 0;
  z-index: 10;
}

.material-table th,
.production-table th,
.batch-material-table th {
  background: linear-gradient(to bottom, #f1f5f9, #e2e8f0);
  color: #334155;
  font-weight: 600;
  padding: 12px 8px;
  text-align: center;
  border-bottom: 1px solid #cbd5e1;
  position: sticky;
  top: 0;
}

/* 表格单元格样式 */
.material-table td,
.production-table td,
.batch-material-table td {
  padding: 10px 8px;
  border-bottom: 1px solid #e2e8f0;
  text-align: center;
  word-break: break-word;
  
}

/* 斑马纹效果 */
.material-table tr:nth-child(even),
.production-table tr:nth-child(even),
.batch-material-table tr:nth-child(even) {
  background-color: #f8fafc;
}

/* 悬停效果 */
.material-table tr:hover,
.production-table tr:hover,
.batch-material-table tr:hover {
  background-color: #f1f5f9;
}

/* 滚动条样式 */
.material-table-container::-webkit-scrollbar,
.production-table-container::-webkit-scrollbar,
.batch-material-table-container::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.material-table-container::-webkit-scrollbar-track,
.production-table-container::-webkit-scrollbar-track,
.batch-material-table-container::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 4px;
}

.material-table-container::-webkit-scrollbar-thumb,
.production-table-container::-webkit-scrollbar-thumb,
.batch-material-table-container::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 4px;
}

.material-table-container::-webkit-scrollbar-thumb:hover,
.production-table-container::-webkit-scrollbar-thumb:hover,
.batch-material-table-container::-webkit-scrollbar-thumb:hover {
  background: #94a3b8;
}

.module {
  /* 移除固定高度或调整为更合适的高度 */
  height: auto; /* 或设置 min-height */
  min-height: 400px;
  max-height: 800px; /* 根据实际需要调整 */
  padding: 20px;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  background-color: #ffffff;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* 确保长文本能自动换行 */
.material-table td,
.production-table td,
.batch-material-table td {
  word-break: break-word;
  white-space: normal;
}

/* 为特定列设置最小宽度 */
.material-table th:nth-child(1),
.production-table th:nth-child(1),
.batch-material-table th:nth-child(1) {
  min-width: 120px;
}

@media (max-width: 1200px) {
  .main-grid {
    grid-template-columns: 1fr;
  }
  
  .material-table-container,
  .production-table-container,
  .batch-material-table-container {
    max-height: 400px;
  }
}

@media (max-width: 768px) {
  .query-section {
    flex-direction: column;
    align-items: stretch;
  }
  
  .query-input {
    width: 100%;
    margin: 10px 0;
  }
  
  .process-grid {
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  }
}

.process-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
}

.process-block {
  text-align: center;
  padding: 15px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.process-block:hover {
  transform: translateY(-3px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.process-block p {
  margin: 5px 0;
}

.process-block p:first-child {
  font-weight: 600;
}

.green {
  background: linear-gradient(to bottom right, #10b981, #059669);
  color: white;
}

.red {
  background: linear-gradient(to bottom right, #ef4444, #dc2626);
  color: white;
}

.text-display {
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 20px 0;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.row {
  display: flex;
  margin-bottom: 0;
}

.showCheckData-header {
  background: linear-gradient(to right, #1e3a8a, #2563eb);
  color: white;
  padding: 12px 10px;
  text-align: center;
  width: 15%;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
}

.item {
  padding: 12px 10px;
  text-align: center;
  width: 30%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid #e2e8f0;
  border-bottom: 1px solid #e2e8f0;
  transition: all 0.2s;
}

.item:hover {
  background-color: #f8fafc;
}

.item p {
  margin: 0;
}

.el-dialog {
  border-radius: 12px;
  overflow: hidden;
}

.el-dialog__header {
  background: linear-gradient(to right, #1e3a8a, #2563eb);
  margin-right: 0;
  padding: 15px 20px;
}

.el-dialog__title {
  color: white;
  font-weight: 600;
}

.el-dialog__body {
  padding: 20px;
}

.divcontainer_sub1 {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 10px;
  background: #f8fafc;
  border-radius: 8px;
  margin-left: 20px;
}

.circle-button {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  margin: 0;
  position: relative;
}

.circle-button::after {
  content: '';
  position: absolute;
  top: -4px;
  left: -4px;
  right: -4px;
  bottom: -4px;
  border-radius: 50%;
  border: 2px solid rgba(0,0,0,0.1);
}

/* 基础样式 */
body {
  background-color: #f1f5f9;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  line-height: 1.6;
  color: #334155;
}

#app {
  max-width: 1800px;
  margin: 0 auto;
  padding: 20px;
}

/* 分割线美化 */
.el-divider {
  margin: 25px 0;
}

.el-divider__text {
  background: #f1f5f9;
  padding: 0 15px;
  color: #64748b;
  font-size: 14px;
}

/* 滚动条美化 */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: #94a3b8;
}
</style>